import 'dart:io';

import 'package:common_utils/common_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter_framework_master/utils/AppUpDate.dart';
import 'package:flutter_framework_master/utils/NetworkType.dart';
import 'package:flutter_framework_master/utils/PersistentStorage.dart';

import 'HttpConfig.dart';

/**
 *Created by Jcy
 *on 2021/9/28
 */
// 引入请求的公共配置，例如 baseUrl等
// 引入本地缓存插件，用来获取本地缓存中的用户信息
class HttpHelper {
  // 封装 dio 请求类
  // dio 的 options 配置
  static BaseOptions _options = new BaseOptions(
    baseUrl: HttpConfig.baseUrl, // 请求的baseUrl
    connectTimeout: 10000, // 连接超时时间
    receiveTimeout: 15000, // 响应超时时间
    contentType: HttpConfig.contentType['Content-Type'],
  );

  // get 请求
  static get(url, {params, needCode = false, cancelToken}) async {
    return await request(url, params, 'GET', needCode);
  }

  // post 请求
  // 上传文件请求
  /*
   * @description: 上传文件请求
   * FormData params = FormData.fromMap({
   * "userid": userid,
   * "file": MultipartFile.fromFileSync(_image),
   * });
   */

  static post(
    url, {
    params,
    needCode = false,
  }) async {
    return await request(
      url,
      params,
      'POST',
      needCode,
    );
  }

  // put 请求
  static put(
    url, {
    params,
    needCode = false,
  }) async {
    return await request(url, params, 'PUT', needCode);
  }

  // delete 请求
  static delete(urlName,
      {params, needCode = false, cancelToken}) async {
    return await request(
      urlName,
      params,
      'DELETE',
      needCode,
    );
  }

  /*
   * @description: 封装请求
   * @param {type}
   * url          请求主路径连接
   * pathParams   连接请求参数类型为：https://test_api.com/user/:id/:name
   * params       请求参数在 body 中，或者为：https://test_api.com/user?id=123&name=zhangsan
   * method       请求方法
   * header       请求头重置
   * needCode     是否需要状态码
   * @return {type}   返回响应数据
   */
  static request(url, params, method, needCode) async {
    if (await NetworkType.isConnected()) {
      // 读取本地缓存中的数据
      // String token = await PersistentStorage.instance.getStorage('token');
      Map headers = {};
      // 存储 请求头 参数
      headers['Accept'] = HttpConfig.contentType['Accept'];
      //  授权信息 Authorization / token
      // if (ObjectUtil.isNotEmpty(token)) {
      // 处理授权信息不存在的逻辑，即 重新登录 或者 获取授权信息
      //   headers['token'] = token;
      // }

      // 设置请求头
      _options.headers = new Map<String, dynamic>.from(headers);

      // 初始化 Dio
      Dio _dio = new Dio(_options);

      // 请求拦击
      _dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
        // Do something before request is sent
        return handler.next(options); //continue
        // 如果你想完成请求并返回一些自定义数据，你可以resolve一个Response对象 `handler.resolve(response)`。
        // 这样请求将会被终止，上层then会被调用，then中返回的数据将是你的自定义response.
        //
        // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`handler.reject(error)`，
        // 这样请求将被中止并触发异常，上层catchError会被调用。
      }, onResponse: (response, handler) {
        // Do something with response data
        return handler.next(response); // continue
        // 如果你想终止请求并触发一个错误,你可以 reject 一个`DioError`对象,如`handler.reject(error)`，
        // 这样请求将被中止并触发异常，上层catchError会被调用。
      }, onError: (DioError e, handler) {
        // Do something with response error
        return handler.next(e); //continue
        // 如果你想完成请求并返回一些自定义数据，可以resolve 一个`Response`,如`handler.resolve(response)`。
        // 这样请求将会被终止，上层then会被调用，then中返回的数据将是你的自定义response.
      }));
      Response? response;
      // dio 请求处理
      try {
        response = await _dio.request(url,
            data: params, options: Options(method: method));
      } on DioError catch (e) {
        // 请求错误处理  ,错误码 e.response.statusCode
        print('请求错误处理： ${e.response!.statusCode}');
        handleHttpError(e.response!.statusCode!);
        if (CancelToken.isCancel(e)) {
          print('请求取消! ' + e.message);
        } else {
          // 请求发生错误处理
          if (e.type == DioErrorType.connectTimeout) {
            print('连接超时');
          }
        }
      }

      // 对相应code的处理
      if (response == null) {
        print('响应错误');
      } else if (needCode) {
        // 需要返回code
        return response.data;
      } else if (!needCode) {
        // 不需要返回 code ，统一处理不同 code 的情况
        if (response.data != '' && response.data != null) {
          // 可对其他不同值的 code 做额外处理
          return response.data['data'];
        } else {
          print('其他数据类型处理');
          return response;
        }
      }
    } else {
      handleHttpError(404);
    }
  }

  /*
   * @description: 处理Http错误码
   * @param {type} 错误码
   * @return {type}
   */
  static handleHttpError(int errorCode) {
    print('http错误码： $errorCode');
  }

  loadImage(String urlStr) async {
    print(urlStr);
    String savePath = '';

    bool hasPermission = await AppUpDate.checkPermission();
    if (hasPermission) {
      var _localPath = (await AppUpDate.findLocalPath())! + 'Download1';
      final savedDir = Directory(_localPath);
      bool hasExisted = await savedDir.exists();
      if (!hasExisted) {
        await savedDir.create();
      }
      String path =
          "${savedDir.path}/${urlStr.substring(urlStr.lastIndexOf("/") + 1)}";

      Response response;
      Dio dio = Dio();

      response = await dio.download(urlStr, path,
          onReceiveProgress: AppUpDate.showDownloadProgress);

      if (response.statusCode == 200) {
        savePath = path;
      }
    }
    return savePath;
  }
}
